/**
 * 
 */
package com.colombounplug.geoshopper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import javax.net.ssl.HttpsURLConnection;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

/**
 * @author anuradha.uduwage
 *
 */
public class MapTabView extends MapActivity {

	MapView mapView = null;
	MapController mapController = null;
	LocationManager mLocationManager;
	LocationListener locationListner;
	Location lastKnownLocation = null;
	public static Context myContext;
	GeoPoint aPoint = null;
	URL bestbuyUrl;
	Product product;
	String apiUrl = null;
	String searchString = null;
	private MyLocationOverlay myLocation;
	
	ArrayList<String> items = new ArrayList<String>();
	private static final Drawable whiteBalloon = new SpotBalloon(255,255,140,0); 
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		GlobalState gs = (GlobalState) getApplication();
		items = gs.getItems();
		
		for(int i=0; i < items.size(); i++) {
			if(searchString == null) {
				searchString = items.get(i) + "*,";
			}
			else {
				searchString = searchString + "*," + items.get(i);
			}
			Log.v("URL:", "STRING: " + searchString);
		}
		Log.v("URL:", "STRING: " + searchString);
		System.out.println("***********" + searchString);
		
		
		myContext = this;
		setContentView(R.layout.maptabview);
		mapView = (MapView)findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mapView.getController().setZoom(16);

		mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
		String locationProvider = LocationManager.NETWORK_PROVIDER;
		lastKnownLocation = mLocationManager.getLastKnownLocation(locationProvider);
		if(lastKnownLocation == null) {
			locationProvider = LocationManager.GPS_PROVIDER;
			lastKnownLocation = mLocationManager.getLastKnownLocation(locationProvider);
		}
		if(lastKnownLocation != null) {
			int lat = (int)lastKnownLocation.getLatitude() * 1000000;
			int lng = (int)lastKnownLocation.getLongitude() * 1000000;
			aPoint = new GeoPoint(lat, lng);
		}	
		
		locationListner = new LocationListener() {
			
			@Override
			public void onStatusChanged(String provider, int status, Bundle extras) {
				Log.v("TEST", "TEST");
			}
			
			@Override
			public void onProviderEnabled(String provider) {
				
			}
			
			@Override
			public void onProviderDisabled(String provider) {
				
			}
			
			@Override
			public void onLocationChanged(Location location) {
				lastKnownLocation = location;
				int lat = (int)((lastKnownLocation.getLatitude() * 1000000));
				int lng = (int)((lastKnownLocation.getLongitude() * 1000000));
				Log.v("DEBUG", "LAT "+ lat);
				Log.v("DEBUG", "LNG" + lng );
				aPoint = new GeoPoint(lat, lng);
				mapView.getController().setCenter(aPoint);
				MapTabView map = new MapTabView();
				HashMap<String, ArrayList<String>> cordinates  = new HashMap<String, ArrayList<String>>();
						
				try {
					try {
						
						cordinates = map.processRequest(map.storeSearchRequest(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()));
						//String test = map.addressWithDistance(map.storeSearchRequest(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()));
						//product.setAddress(test);
					} catch (IllegalStateException e) {
						e.printStackTrace();
					} catch (JSONException e) {
						e.printStackTrace();
					}
				} catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}					
				overlayMethod(cordinates);
				
			}			
		};
		
		if(mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListner);
		} 
		else {
			mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListner);
		}
		
		//mapView.getController().setCenter(aPoint);
		if(aPoint != null)
			mapView.getController().setCenter(aPoint);
	}
	
	public void overlayMethod(HashMap<String, ArrayList<String>> map) {
		OverlayItem overlayitem = null;
		List<Overlay> mapOverlays;
		StoreMarkerLayer privateLayer;
		
		mapOverlays = mapView.getOverlays();
		
		if(!mapOverlays.isEmpty()) {
			mapOverlays.clear();
			mapView.invalidate();
		}
		
		Drawable drawable = this.getResources().getDrawable(R.drawable.shoppinglog);
		
		GeoPoint point = null;

		for(Entry<String, ArrayList<String>> entry : map.entrySet() ) {
			Log.v("Lat Value " + entry.getKey(), "Lng Value " + entry.getValue());
			int a = 0;
			int b = 0;
			String[] points = null;
			points = entry.getKey().split(",");
			//for(int i =0; i < points.length; i++) {
			a = (int) (Double.parseDouble(points[0]) * 1000000);
			b = (int) (Double.parseDouble(points[1]) * 1000000);
			//}
				
			Log.v("Print A ", "a" + a);
			Log.v("Print B ", "b" + b);
			point = new GeoPoint(a,b);
			String priceinfo = null;
			privateLayer = new StoreMarkerLayer(drawable, this);
			for(int i =0; i < entry.getKey().length(); i++) {
				Log.v("VALUE ", "Hash " + entry.getValue().get(i));
				for(int j = 0; j < items.size(); j++) {
					if(entry.getValue().get(i).contains(items.get(j))) {
							priceinfo = entry.getValue().get(i);
					}
				}
				overlayitem = new OverlayItem(point, "Items", entry.getValue().get(i) + entry.getValue().get(i+1));
				privateLayer.addOverlayItem(overlayitem);
				mapOverlays.add(privateLayer);
			}
				
		}
		myLocation = new MyLocationOverlay(this, mapView);
		myLocation.enableMyLocation();
		myLocation.enableCompass();
		mapView.getOverlays().add(myLocation);
	}

	/*
    //pauses listener while app is inactive
    @Override
    public void onPause() {
        super.onPause();
        locationManager.removeUpdates(onLocationChange);
    }
    
    //reactivates listener when app is resumed
    @Override
    public void onResume() {
        super.onResume();
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,10000.0f,onLocationChange);
    }
	*/
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	/**
	 * Make the http request and return the respose as a string.
	 * @return
	 * @throws MalformedURLException
	 * @throws IOException
	 */
	public String storeSearchRequest(double lat, double lng) throws MalformedURLException, IOException {
		//String url = "http://api.remix.bestbuy.com/v1/stores%28area%28"+ lat + "," + lng +",10%29%29?apiKey=zau6a4zrzqg85htmd72pvb3j&format=json";
		String url = "http://api.remix.bestbuy.com/v1/stores%28area%28" + lat + "," + lng  + ",10%29%29+products%28name=ipod*%29?apiKey=zau6a4zrzqg85htmd72pvb3j&format=json";
		if(searchString == null) {
			searchString = "ipod*,macbook*";
		}
		String apiUrl = "http://api.remix.bestbuy.com/v1/stores%28area%28"+ + lat + "," + lng + ",10%29%29+products(name%20in("+ searchString +"))?apiKey=zau6a4zrzqg85htmd72pvb3j&format=json";
		
		//String test = "http://api.remix.bestbuy.com/v1/stores%28area%2894103,10%29%29+products(name%20in(ipod*,iphone*))?apiKey=zau6a4zrzqg85htmd72pvb3j&format=json";
		StringBuilder respose = new StringBuilder();
		Log.v("storesearch", "url : " + apiUrl);
		bestbuyUrl = new URL(apiUrl);
		
		HttpURLConnection httpConn = (HttpURLConnection) bestbuyUrl.openConnection();
		if(httpConn.getResponseCode() == HttpsURLConnection.HTTP_OK) {
			BufferedReader input = new BufferedReader(new InputStreamReader(httpConn.getInputStream()), 8192);
			String strLine = null;
			while((strLine = input.readLine()) != null) {
				respose.append(strLine);
			}
			input.close();
		}
		return respose.toString();
	}
	
	/**
	 * Parse JSON request and return a hash map with locations.
	 * @param resp
	 * @return
	 * @throws IllegalStateException
	 * @throws IOException
	 * @throws JSONException
	 */
	public HashMap<String, ArrayList<String>> processRequest(String resp) throws IllegalStateException, IOException, JSONException {
		StringBuilder sb = new StringBuilder();
		ArrayList<String> addressLocation = new ArrayList<String>();
		HashMap<String, ArrayList<String>>latLngNdProduct = new HashMap<String, ArrayList<String>>();
		//Log.v("storesearch", "results : " + resp);
		JSONObject mResponseObject = new JSONObject(resp);
		//JSONObject responObject = mResponseObject.getJSONObject("stores");
		JSONArray array = mResponseObject.getJSONArray("stores");
		Log.v("storesearch", "number of results " + array.length());
		for(int i = 0; i < array.length(); i++) {
			Log.v("result " + i, " + " + array.get(i).toString());
			JSONObject jobj = (JSONObject) array.get(i);
			String lat = array.getJSONObject(i).getString("lat");
			String lng = array.getJSONObject(i).getString("lng");
			Log.v("lat ", lat);
			Log.v("lng ", lng);
			//latNlng.put(lat, lng);
			//JSONObject addressPrice = (JSONObject) jobj.get("products");
			JSONArray productArray = new JSONArray();
			productArray = jobj.getJSONArray("products");
			for(int j =0; j < productArray.length(); j++) {
				addressLocation.add("Sale Price" + productArray.getJSONObject(j).getString("salePrice"));
				Log.v("SALE PRICE:", "$" + productArray.getJSONObject(j).getString("salePrice"));
				addressLocation.add("Name" + productArray.getJSONObject(j).getString("name"));
				Log.v("NAME:", "$" + productArray.getJSONObject(j).getString("name"));
			}
			latLngNdProduct.put(lat + "," + lng, addressLocation);
		}
		return latLngNdProduct;
	}
	
	public String addressWithDistance(String resp) throws JSONException {
		String address = null;
		String distance = null;
		JSONObject jsonObject = new JSONObject(resp);
		JSONArray storeArray = jsonObject.getJSONArray("stores");
		for (int i = 0; i < storeArray.length(); i++) {
			address = storeArray.getJSONObject(i).getString("address");
			distance = storeArray.getJSONObject(i).getString("distance");
			product = new Product(address, distance);
		}
		return address + distance;
	}

}
